To be able to edit code and run cells, you need to run the notebook yourself. Where would you like to run the notebook?

This notebook takes about 30 seconds to run.

In the cloud (experimental)

Binder is a free, open source service that runs scientific notebooks in the cloud! It will take a while, usually 2-7 minutes to get a session.

On your computer

(Recommended if you want to store your changes.)

  1. Copy the notebook URL:
  2. Run Pluto

    (Also see: How to install Julia and Pluto)

  3. Paste URL in the Open box

Frontmatter

If you are publishing this notebook on the web, you can set the parameters below to provide HTML metadata. This is useful for search engines and social media.

Author 1
👀 Reading hidden code
using HypertextLiteral
: @htl, @htl_str

25.8 ms
👀 Reading hidden code
material_header = @htl """
<link href="https://unpkg.com/material-components-web@13.0.0/dist/material-components-web.min.css" rel="stylesheet">
<script src="https://unpkg.com/material-components-web@13.0.0/dist/material-components-web.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
"""
60.7 μs
👀 Reading hidden code
@htl """
<span>
<button class="mdc-button foo-button">
<div class="mdc-button__ripple"></div>
<span class="mdc-button__label">Button</span>
</button>
<script>
mdc.ripple.MDCRipple.attachTo(currentScript.parentElement.querySelector('button'));
</script>
</span>
"""
43.7 μs

Hello!

Wowwaeiofdsi fjklas djflkasj dflkasjd flkasd fklzsjd fkja sdf

👀 Reading hidden code
content = @htl """
<h3 class="mdc-typography--headline3">Hello!</h3>
<p>Wowwaeiofdsi fjklas djflkasj dflkasjd flkasd fklzsjd fkja sdf </p>
"""
67.6 μs

Hello!

Wowwaeiofdsi fjklas djflkasj dflkasjd flkasd fklzsjd fkja sdf

@htl """<div class="mdc-card mdc-typography ">

$(content)
</div>"""
👀 Reading hidden code
456 ms
missing
xo
👀 Reading hidden code
9.8 μs
yayo
👀 Reading hidden code
9.2 μs
yayo = @bind xo @htl """
<span>
<div class="mdc-slider mdc-slider--range">
<input class="mdc-slider__input" type="range" min="0" max="70" value="30" name="rangeStart" aria-label="Continuous range slider demo">
<input class="mdc-slider__input" type="range" min="30" max="100" value="70" name="rangeEnd" aria-label="Continuous range slider demo">
<div class="mdc-slider__track">
<div class="mdc-slider__track--inactive"></div>
<div class="mdc-slider__track--active">
<div class="mdc-slider__track--active_fill"></div>
</div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
</div>
<script>
let root = currentScript.parentElement

let coolslider = mdc.slider.MDCSlider.attachTo(root.querySelector('.mdc-slider'));

let value = [30,70]

Object.defineProperty(root, 'value', {
get: () => value,
set: (newval) => {
value = newval;
coolslider.setValue(newval[1])
coolslider.setValueStart(newval[0])
}
})

coolslider.root.addEventListener('MDCSlider:input', (e)=>{
value = [coolslider.getValueStart(), coolslider.getValue(), ]
root.dispatchEvent(new CustomEvent("input"))
});
</script>
</span>
"""
👀 Reading hidden code
492 ms

👀 Reading hidden code
69.5 μs
f (generic function with 1 method)
f(;kwargs...) = kwargs
👀 Reading hidden code
979 μs
f(; x = 1, a..., c...)
👀 Reading hidden code
13.6 ms
c = (Symbol(k) => v for (k,v) in b)
👀 Reading hidden code
4.1 ms
a = (x = 123,)
👀 Reading hidden code
15.4 μs
using JSON
👀 Reading hidden code
82.8 ms
b = JSON.parse("{\"a\": 1}")
👀 Reading hidden code
3.9 s
f(; a..., x = 1)
👀 Reading hidden code
4.7 ms
# @htl """
# <style>
# .cards {
# display: flex;
# flex-wrap: wrap;
# }

# .element-card {
# width: 20em;
# margin: 16px;
# }

# .element-card > .mdc-card__media {
# height: 9em;
# }

# #demo-absolute-fab {
# position: fixed;
# bottom: 1rem;
# right: 1rem;
# z-index: 1;
# }
# </style>
# <div class="mdc-typography">
# <h1>Choose your element</h1>
# <div class="cards">
# <div class="mdc-card element-card earth">
# <div class="mdc-card__media">
# <div class="mdc-card__media-content">
# <h1 class="mdc-typography--headline4">Earth</h1>
# <h2 class="mdc-typography--headline6">A solid decision.</h2>
# </div>
# </div>
# <p>
# Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
# Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
# </p>
# </div>
# <div class="mdc-card element-card wind">
# <div class="mdc-card__media">
# <h1 class="mdc-typography--headline4">Wind</h1>
# <h2 class="mdc-typography--headline6">Stormy weather ahead.</h2>
# </div>
# <p>
# Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
# Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
# </p>
# </div>
# <div class="mdc-card element-card fire">
# <div class="mdc-card__media">
# <h1 class="mdc-typography--headline4">Fire</h1>
# <h2 class="mdc-typography--headline6">Hot-headed much?</h2>
# </div>
# <p>
# Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
# Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
# </p>
# </div>
# <div class="mdc-card element-card water">
# <div class="mdc-card__media">
# <h1 class="mdc-typography--headline4">Water</h1>
# <h2 class="mdc-typography--headline6">Go with the flow.</h2>
# </div>
# <p>
# Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
# Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
# </p>
# </div>
# </div>
# <button class="mdc-fab" id="demo-absolute-fab" aria-label="Favorite">
# <div class="mdc-fab__ripple"></div>
# <span class="mdc-fab__icon material-icons">favorite</span>
# </button>
# </div>
# """
👀 Reading hidden code
9.8 μs
0
97
zbond
👀 Reading hidden code
9.3 μs
0.0:3.141592653589793:97.38937226128358
z
👀 Reading hidden code
8.4 μs
import AbstractPlutoDingetjes
👀 Reading hidden code
8.5 ms
begin
struct RangeSlider
range::AbstractRange{<:Real}
default::AbstractRange
end

RangeSlider(range; default=range) = RangeSlider(range, default)

function Base.show(io, m::MIME"text/html", rs::RangeSlider)
if !AbstractPlutoDingetjes.is_supported_by_display(io, AbstractPlutoDingetjes.Bonds.transform_value)
write(io, "❌ Update Pluto to use this element.")
return
end
show(io, m, @htl("""
<div>
<link href="https://cdn.jsdelivr.net/npm/nouislider@15.5.0/dist/nouislider.min.css" rel="stylesheet"/>
<script>
const {default: noUiSlider} = await import( "https://cdn.jsdelivr.net/npm/nouislider@15.5.0/dist/nouislider.min.mjs")
const {default: throttle} = await import("https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/throttle.js")
const el = html`<div style='font-family: system-ui; font-size: .75rem; min-height: 1em; margin: 2.5em 1em .5em 1em'></div>`
const step = $(Float64(step(rs.range)))
let num_decimals = Math.max(0, -1 * Math.floor(Math.log(step)))
const formatter = {
to: x => x.toLocaleString("en-US", { maximumFractionDigits: num_decimals, minimumFractionDigits: num_decimals })
}
const slider = noUiSlider.create(el, {
start: [$(Float64(minimum(rs.default))), $(Float64(maximum(rs.default)))],
connect: true,
range: {
'min': $(Float64(minimum(rs.range))),
'max': $(Float64(maximum(rs.range))),
},
tooltips: [formatter, formatter],
step: step,
});
// console.log(slider)
let root = currentScript.parentElement
let busy = false
slider.on("start", () => {busy = true})
slider.on("end", () => {busy = false})
let handler = (e) => {
// console.warn(e, root.value, 123)
root.dispatchEvent(new CustomEvent("input"))
}
slider.on("slide", handler)
slider.on("drag", handler)
invalidation.then(() => {
slider.off("slide", handler)
slider.off("drag", handler)
})
Object.defineProperty(root, 'value', {
get: () => slider.get(true),
set: (newval) => {
if(!busy) {
slider.set(newval)
}
}
})
return el
</script>
</div>
"""))
end

AbstractPlutoDingetjes.Bonds.initial_value(rs::RangeSlider) = rs.default

function AbstractPlutoDingetjes.Bonds.transform_value(rs::RangeSlider, js_val::Any)
@assert js_val isa Vector && length(js_val) == 2
rounded_range = closest.([rs.range], js_val)
rounded_range[1] : step(rs.range) : rounded_range[2]
end

end
👀 Reading hidden code
25.9 ms
closest (generic function with 1 method)
function closest(range::AbstractRange, x::Real)
rmin = minimum(range)
rmax = maximum(range)

if x <= rmin
rmin
elseif x >= rmax
rmax
else
rstep = step(range)

int_val = (x - rmin) / rstep
range[round(Int, int_val) + 1]
end
end
👀 Reading hidden code
1.3 ms
@bind closest_test html"<input type=range step=0.000001 max=5>"
👀 Reading hidden code
34.6 ms
missing
closest_test
👀 Reading hidden code
9.5 μs
Error message

MethodError: no method matching closest(::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, ::Missing)

Closest candidates are:

closest(::AbstractRange, ::Real) at ~/work/disorganised-mess/disorganised-mess/material components.jl#==#7b4689c1-7eba-4939-8618-7525c82f57cf:1

Stack trace

Here is what happened, the most recent locations are first:

  1. closest(2:.3:4, closest_test)
closest(2:.3:4, closest_test)
👀 Reading hidden code
---
0
97
zbond = @bind z RangeSlider(0.0:π:100)
👀 Reading hidden code
46.7 ms
1.000000
10.000000
@bind rational RangeSlider(1:1//300:10)
👀 Reading hidden code
67.2 ms
1//1:1//300:10//1
rational
👀 Reading hidden code
10.5 μs
Float64.(rational)
👀 Reading hidden code
60.3 ms

👀 Reading hidden code
78.2 μs